package fschmidt.util.executor;

import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public final class ScheduledThreadPool extends AbstractThreadPool {
	private static final Logger logger = LoggerFactory.getLogger(ScheduledThreadPool.class);

	private final SortedMap<Long,Runnable> queue = new TreeMap<Long,Runnable>();

	public ScheduledThreadPool(int size) {
		super(size);
		start();
	}

	public final synchronized void schedule(Runnable command,long delay,TimeUnit unit) {
		if( !isRunning() )
			return;
		long when = System.currentTimeMillis() + unit.toMillis(delay);
		command = wrap(command);
		while(true) {
			command = queue.put(when,command);
			if( command == null )
				break;
			when++;
		}
		notify();
	}

	@Override synchronized Runnable getCommand() {
		while(true) {
			try {
				while( queue.isEmpty() ) {
					if( !isRunning() )
						return null;
					wait();
				}
				long first = queue.firstKey();
				long now = System.currentTimeMillis();
				if( first <= now )
					return queue.remove(first);
				if( !isRunning() )
					return null;
				wait( first - now );
			} catch(InterruptedException e) {
				logger.error("",e);
			}
		}
	}

	@Override public final synchronized int getQueueSize() {
		return queue.size();
	}

}
